﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Net.Sockets;

namespace displaycongress_desktop
{
    public class SocketDecoder
    {
        private List<UserSocket> clients = new List<UserSocket>();

        public SocketDecoder() {}
        
        public void decode(String str, Socket client)
        {
            Dictionary<String, String> set = SocketDecoder.XMLToSet(str);
            if (set.ContainsKey("type") && set["type"].Equals("login"))
            {
                Boolean connect = LoginDecoder.connect(set["name"], set["data"]);

                if (connect)
                {
                    addClient(set["name"], client.RemoteEndPoint.ToString().Split(':')[0].Trim());
                    AsynchronousSocketListener.Send(client, "_loggedin_");
                }
            }
            else if (isClient(client) && set.ContainsKey("type") && set["type"].Equals("file"))
            {
                FileDecoder fileDecoder = new FileDecoder(set["name"], set["data"]);
            }
            else if (isClient(client) && set.ContainsKey("type") && set["type"].Equals("url"))
            {
                Console.WriteLine("url: " + set["data"]);
                URLDecoder urlDecoder = new URLDecoder(set["data"]);
            }
            else
            {
                Console.WriteLine("Not connected!!");
                AsynchronousSocketListener.Send(client, "_loggedin_");
            }

            set.Clear();
        }

        private static Dictionary<String, String> XMLToSet(String str)
        {
            Dictionary<String, String> set = new Dictionary<String, String>();

            String findTagString = "(?<=>)|(?=<)";
            Regex findTag = new Regex(findTagString);
            String[] tags = Regex.Split(str, findTagString);

            String tag = "";
            String value = "";
            int foundAt = 0;
            for (int i = 0; i < tags.Length; i++)
            {
                if (tags[i].IndexOf('<') > -1 && tags[i].IndexOf('>') > -1 && tag == "")
                {
                    tag = tags[i].Replace('<', ' ').Replace('>', ' ').Trim();
                    foundAt = i;
                }
                else if (tags[i].IndexOf('<') > -1 && tags[i].IndexOf('>') > -1 && tags[i].Replace('<', ' ').Replace('>', ' ').Trim().Equals("/" + tag))
                {
                    if (!set.ContainsKey(tag))
                    {
                        set.Add(tag, value);
                    }

                    tag = "";
                    value = "";
                }
                else
                {
                    value += tags[i];
                }
            }

            return set;
        }

        private void addClient(String name, String client)
        {
            if (!isClient(client))
            {
                Console.WriteLine(name + " - " + client);
                clients.Add(new UserSocket(client, name));
                Console.WriteLine(clients.Count);
            }
            else
            {
                Console.WriteLine("Already connected");
            }
        }

        private Boolean removeClient(String client)
        {
            foreach (UserSocket user in clients)
            {
                if (user.getClient().Equals(client))
                {
                    return clients.Remove(user);
                }
            }
            
            return false;
        }

        private Boolean isClient(String client)
        {
            foreach (UserSocket user in clients)
            {
                Console.WriteLine(user.getClient());
                if (user.getClient().Equals(client))
                {
                    return true;
                }
            }

            return false;
        }

        private Boolean isClient(Socket client)
        {
            return isClient(client.RemoteEndPoint.ToString().Split(':')[0].Trim());
        }
    }
}
